package me.yiyou.meihua.ui.page.dateqiuga

import androidx.compose.runtime.State
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.gson.Gson
import com.kongzue.dialogx.dialogs.PopTip
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import me.yiyou.meihua.MyApplication
import me.yiyou.meihua.R
import me.yiyou.meihua.data.BaGuaImage
import me.yiyou.meihua.data.LunarDate
import me.yiyou.meihua.data.SaveBean
import me.yiyou.meihua.data.xinghuo.ChatMessage
import me.yiyou.meihua.data.xinghuo.ChatUiState
import me.yiyou.meihua.data.xinghuo.XHFlowResponse
import me.yiyou.meihua.data.xinghuo.XHResponse
import me.yiyou.meihua.data.xinghuo.XingHuoMessage
import me.yiyou.meihua.data.xinghuo.XingHuoTool
import me.yiyou.meihua.data.xinghuo.XingHuoWebSearch
import me.yiyou.meihua.data.xinghuo.XingHuoX1
import me.yiyou.meihua.net.ApiService
import me.yiyou.meihua.net.RetrofitClient
import me.yiyou.meihua.utils.LogUtil
import me.yiyou.meihua.utils.getMeiHuaDongYao
import me.yiyou.meihua.utils.getMeiHuaShang
import me.yiyou.meihua.utils.getMeiHuaXia
import me.yiyou.meihua.utils.getYMDHmethod
import okhttp3.ResponseBody
import okio.Buffer
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.UUID


class DateQiGuaViewModel : ViewModel() {
    // 注入repository
    val meiHuaRepository = MyApplication.appContext.meiHuaRepository

    // 占问事
    private val _inputContent = mutableStateOf("")
    val inputContent: State<String> = _inputContent

    // 控制显示占问页面
    private val _showDescribe = mutableStateOf(true)
    val showDescribe: State<Boolean> = _showDescribe

    // 卦象数据
    val shangGua = mutableIntStateOf(0)
    val xiaGua = mutableIntStateOf(0)
    val dongYao = mutableIntStateOf(0)

    // 占问时间
    val now = LocalDateTime.now()
    val time = now.format("yyyy/MM/dd HH:mm:ss")

    // ai
    private val _chatResponse = MutableStateFlow<XHResponse?>(null)
    val chatResponse = _chatResponse.asStateFlow()

    // ai button
    private val _aiButton = mutableStateOf(true)
    val aiButton: State<Boolean> = _aiButton

    //#region ai 流式回复布局,ai写的
    private val apiService = RetrofitClient.createService(ApiService::class.java)

    // UI状态
    private val _uiState = MutableStateFlow<ChatUiState>(ChatUiState.Idle)
    val uiState: StateFlow<ChatUiState> = _uiState

    // 当前会话消息
    private val _messages = MutableStateFlow<List<ChatMessage>>(emptyList())
    val messages: StateFlow<List<ChatMessage>> = _messages

    // 当前正在更新的助手消息ID（用于流式响应）
    private var currentAssistantMessageId: String? = null

    // 发送消息
    fun sendMessage(userMessage: String) {
        viewModelScope.launch {
            try {
                // 添加用户消息
//                addUserMessage(userMessage)
                // 创建请求体
                val request = XingHuoX1(
                    model = "x1",
                    user = "yiyou236",
                    messages = listOf(XingHuoMessage(role = "user", content = userMessage)),
                    stream = true,
                    max_tokens = 10000,
                    tools = if (true) {
                        listOf(
                            XingHuoTool(
                                type = "web_search", web_search = XingHuoWebSearch(
                                    enable = true, search_mode = "deep"
                                )
                            )
                        )
                    } else null
                )

                // 更新UI状态
                _uiState.value = ChatUiState.Loading
                _aiButton.value = false

                // 发起流式请求
                val response = apiService.chatStream(request)
                // 添加初始助手消息占位符
                launch(Dispatchers.IO) {
                    addAssistantPlaceholder()
                    parseStreamResponse(response)
                }

            } catch (e: Exception) {
                _uiState.value = ChatUiState.Error(e.message ?: "Network error")
            }
        }
    }

    // 解析流式响应
    private suspend fun parseStreamResponse(body: ResponseBody) {
        val source = body.source()
        val buffer = Buffer()

        while (!source.exhausted()) {
            val line = source.readUtf8Line() ?: continue

            when {
                line.isBlank() -> continue
                line == "data: [DONE]" -> {
                    handleStreamComplete()
                    break
                }

                line.startsWith("data: ") -> {
                    val json = line.substring(6) // 移除"data: "前缀
                    handleDataChunk(json)
                }
            }
        }
    }

    // 处理数据块
    private fun handleDataChunk(json: String) {
        try {
            val response = Gson().fromJson(json, XHFlowResponse::class.java)
            if (response.code != 0) return

            // 获取内容块
            val chunk = response.choices.firstOrNull()?.delta?.reasoningContent
                ?: response.choices.firstOrNull()?.delta?.content ?: return

            // 更新UI
            updateAssistantMessage(chunk)
        } catch (e: Exception) {
            LogUtil.e("Error parsing data chunk")
        }
    }

    // 更新助手消息内容（流式追加）
    private fun updateAssistantMessage(chunk: String) {
        val currentId = currentAssistantMessageId ?: return

        _messages.update { currentMessages ->
            currentMessages.map { message ->
                if (message.id == currentId) {
                    message.copy(text = message.text.replace("|", "") + chunk)
                } else {
                    message
                }
            }
        }
    }

    // 流式处理完成
    private fun handleStreamComplete() {
        // 移除加载占位符
        _messages.update { currentMessages ->
            currentMessages.map { message ->
                if (message.id == currentAssistantMessageId) {
                    message.copy(text = message.text.replace("|", ""))
                } else {
                    message
                }
            }
        }

        currentAssistantMessageId = null
        _uiState.value = ChatUiState.Success
    }

    // 添加用户消息
    private fun addUserMessage(text: String) {
        _messages.update { current ->
            current + ChatMessage(
                id = UUID.randomUUID().toString(),
                text = text,
                isUser = true
            )
        }
    }

    // 添加助手消息占位符
    private fun addAssistantPlaceholder() {
        val placeholder = ChatMessage(
            id = UUID.randomUUID().toString(),
            text = "|", // 加载动画占位符
            isUser = false
        )
        currentAssistantMessageId = placeholder.id
        _messages.update { it + placeholder }
    }

    //#endregion

    /**
     * 获取ai回复
     */
    fun getChatResponse(
        model: String, userId: String, userMessage: String, callback: (Result<XHResponse>) -> Unit
    ) {
        _aiButton.value = false
        viewModelScope.launch {
            val result = meiHuaRepository.getChatCompletion(
                model = model, userId = userId, userMessage = userMessage
            )
            _chatResponse.value = result.getOrNull()
            callback(result)
        }
    }

    /**
     * 时间格式化
     */
    fun LocalDateTime.format(pattern: String): String =
        this.format(DateTimeFormatter.ofPattern(pattern))

    /**
     * 占问事, 输入内容变化监听
     */
    fun onInputContentChange(content: String) {
        _inputContent.value = content
    }

    /**
     * 起卦
     */
    fun qiGua() {
        if (inputContent.value.isNotEmpty()) {
            _showDescribe.value = false // 隐藏占问事页面
        } else {
            PopTip.show(R.drawable.icon_error, "请输入占问事内容")
            return
        }
        // 获取年月日时,农历
        val lunarDate: LunarDate = getYMDHmethod()

        // 获取卦
        shangGua.intValue = getMeiHuaShang(lunarDate)
        xiaGua.intValue = getMeiHuaXia(lunarDate)
        // 动爻
        dongYao.intValue = getMeiHuaDongYao(lunarDate)

        // 起卦存入数据库,因为里面是suspend函数,所以需要用viewModelScope
        viewModelScope.launch(Dispatchers.IO) {
            try {
                var saveBean = SaveBean(
                    shang = shangGua.intValue,
                    xia = xiaGua.intValue,
                    dong = dongYao.intValue,
                    time = time,
                    content = inputContent.value
                )
                meiHuaRepository.insert(saveBean)
            } catch (e: Exception) {
                LogUtil.e("插入失败: ${e.message}")
            }
        }
    }

    /**
     * 画卦
     */
    fun paintGua(shang: Int, xia: Int, dong: Int? = null): BaGuaImage {
        var baguaImage: BaGuaImage = BaGuaImage(false, false, false, false, false, false)
        when (shang) {
            1 -> {
                baguaImage.six = true
                baguaImage.five = true
                baguaImage.four = true
            }

            2 -> {
                baguaImage.six = false
                baguaImage.five = true
                baguaImage.four = true
            }

            3 -> {
                baguaImage.six = true
                baguaImage.five = false
                baguaImage.four = true
            }

            4 -> {
                baguaImage.six = false
                baguaImage.five = false
                baguaImage.four = true
            }

            5 -> {
                baguaImage.six = true
                baguaImage.five = true
                baguaImage.four = false
            }

            6 -> {
                baguaImage.six = false
                baguaImage.five = true
                baguaImage.four = false
            }

            7 -> {
                baguaImage.six = true
                baguaImage.five = false
                baguaImage.four = false
            }

            0 -> {
                baguaImage.six = false
                baguaImage.five = false
                baguaImage.four = false
            }
        }
        when (xia) {
            1 -> {
                baguaImage.three = true
                baguaImage.two = true
                baguaImage.one = true
            }

            2 -> {
                baguaImage.three = false
                baguaImage.two = true
                baguaImage.one = true
            }

            3 -> {
                baguaImage.three = true
                baguaImage.two = false
                baguaImage.one = true
            }

            4 -> {
                baguaImage.three = false
                baguaImage.two = false
                baguaImage.one = true
            }

            5 -> {
                baguaImage.three = true
                baguaImage.two = true
                baguaImage.one = false
            }

            6 -> {
                baguaImage.three = false
                baguaImage.two = true
                baguaImage.one = false
            }

            7 -> {
                baguaImage.three = true
                baguaImage.two = false
                baguaImage.one = false
            }

            0 -> {
                baguaImage.three = false
                baguaImage.two = false
                baguaImage.one = false
            }
        }

        return baguaImage
    }
}